/*
 * Copyright (C), 2002-2016, 苏宁易购电子商务有限公司
 * FileName: ModelCheckServiceImpl.java
 * Author:   13075787
 * Date:     2016年7月6日 下午3:17:09
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.intf.model.CacheKeyModelConstants;
import com.suning.sawp.intf.model.ModelCheckListBean;
import com.suning.sawp.intf.model.ModelCheckVo;
import com.suning.sawp.intf.model.ModelCommodityBaseInfo;
import com.suning.sawp.intf.model.ModelConstant;
import com.suning.sawp.intf.model.ModelMainListBean;
import com.suning.sawp.intf.model.ModelManageService;
import com.suning.sawp.intf.model.ModelPriceIdCheckBean;
import com.suning.sawp.intf.model.ModelTaskAssignDetailsBean;
import com.suning.sawp.intf.model.PriceTagDetail;
import com.suning.sawp.service.util.BeanUtil;
import com.suning.sawp.service.util.RedisCacheUtils;

/**
 * 样机管理-封装<br>
 * 盘点相关
 *
 * @author 13075787
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service("modelCheckService")
public class ModelCheckServiceImpl {

    private static final Logger LOGGER = LoggerFactory.getLogger(ModelCheckServiceImpl.class);

    private static final Integer NUM_ZERO = 0;

    private static final Integer NUM_ONE = 1;

    @Autowired
    ModelCheckDaoServiceImpl modelCheckDaoService;

    @Autowired
    ModelBlendDaoServiceImpl modelBlendDaoService;

    @Autowired
    ModelCommodityInfoServiceImpl modelCommodityInfoService;

    @Resource
    RedisCacheUtils cacheUtils;

    @Autowired
    ModelManageService modelManageService;

    /**
     * 功能描述: <br>
     * 查询样机盘点数据
     *
     * @param storeMan
     * @param taskId
     * @param index
     * @param size
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<List<ModelCheckVo>> queryModelCheckListForStaff(StoreManDto storeMan, Long taskId, Integer index,
            Integer size) {
        ReturnMsg<List<ModelCheckVo>> result = new ReturnMsg<List<ModelCheckVo>>();
        result.setRetFlag(ReturnMsg.SUCCESS);
        List<ModelCheckVo> list = modelCheckDaoService.queryModelCheckListForStaff(taskId, storeMan.getStaffId(), index,
                size);
        // 添加样机属性返回字段
        if (CollectionUtils.isNotEmpty(list)) {
            // 提取出商品编码
            List<String> commCodes = new ArrayList<String>();
            for (ModelCheckVo modelCheckVo : list) {
                commCodes.add(modelCheckVo.getCommCode());
            }
            Map<String, Integer> attrMap = modelBlendDaoService.queryModelAttributes(storeMan.getStoreCode(),
                    commCodes);
            for (ModelCheckVo modelCheckVo : list) {
                modelCheckVo.setAttribute(attrMap.get(modelCheckVo.getCommCode()));
            }
        }
        result.setData(list);
        return result;
    }

    /**
     * 功能描述: <br>
     * 扫码盘点提交
     *
     * @param storeMan
     * @param commCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<ModelCheckVo> saveModelCheck(StoreManDto storeMan, Long taskId, String commCode, String priceId) {
        ReturnMsg<ModelCheckVo> result = new ReturnMsg<ModelCheckVo>();
        result.setRetFlag(ReturnMsg.SUCCESS);
        // 是否已盘点-默认0未盘点
        Integer existFlag = ModelConstant.NUM_ZERO;
        if (StringUtils.isNotBlank(commCode) && null != taskId) {
            String locCommCode = CmmdtyUtils.transform9PartNumber(commCode);
            // 1.先查询这个商品编码的基本信息;不存在直接返回结果
            ModelCommodityBaseInfo modelCommodity = modelCommodityInfoService.queryCommodityBaseInfo(locCommCode);
            // 商品信息为空不存在，直接返回
            if (null == modelCommodity || StringUtils.isBlank(modelCommodity.getCommName())) {
                result.setError(ModelConstant.MODEL_ERROR_NO_COMM,
                        locCommCode + ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_COMM));
                return result;
            }
            // 增加商品品牌判断,如果该品牌不是分配的盘点品牌,不入库
            if (!isOwnInventoryBrand(storeMan.getStoreCode(), storeMan.getStaffId(), 
                    taskId,modelCommodity.getCateCode(),  modelCommodity.getBranch9code())) {
                result.setError(ModelConstant.MODEL_ERROR_NO_MARCH_COMM,
                        ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_MARCH_COMM));
                return result;
            }
            // 2.查询样机清单 1.有 2无插入
            ModelMainListBean modelMain = modelBlendDaoService.queryModelCommInfo(storeMan.getStoreCode(), locCommCode);
            // 样机属性
            Integer attribute = null;
            // 库位编码 默认样机库
            String storageCode = ModelConstant.MODEL_LIB;
            // 商品名称
            String commName = modelCommodity.getCommName();
            // 盘点商品数量
            Integer commNum = NUM_ONE;
            if (null != modelMain) {
                // 样机清单中存在此商品，属性和库位使用已存在值
                attribute = modelMain.getAttribute();
                storageCode = modelMain.getStorageCode();
            } else {
                List<PriceTagDetail> commList = new ArrayList<PriceTagDetail>();
                PriceTagDetail priceTagDetail = new PriceTagDetail();
                priceTagDetail.setCmmdtyCode(locCommCode);
                // 样机库
                priceTagDetail.setCounterFlag("0");
                // 先插入样机清单表
                commList.add(priceTagDetail);
                modelManageService.saveModelList(storeMan.getStoreCode(), commList);
            }
            ModelCheckVo retModelCheck = new ModelCheckVo();
            // 3.查询盘点任务中是否存在
            ModelCheckListBean modelCheck = modelCheckDaoService.queryModelCheckComm(taskId, storeMan.getStaffId(),
                    locCommCode);
            // 更新商品数量-缓存中价签的数量
            ModelPriceIdCheckBean priceCheck = this.getTheCommNum(storeMan.getStoreCode(), storeMan.getStaffId(),
                    locCommCode, priceId);
            // 若存在，则更新商品数量；若不存在，则插入
            if (null != modelCheck) {
                commNum = modelCheck.getCheckCommNum();
                Integer countNum = priceCheck.getCheckNum();
                // 存在，则为已盘点
                if (priceCheck.isCheckFlag()) {
                    existFlag = ModelConstant.NUM_ONE;
                }
                // 若当前盘点的数量小于价签的数量，则用价签数量覆盖(作为)盘点数量
                if (null != commNum) {
                    if (commNum.compareTo(countNum) < 0) {
                        commNum = countNum;
                        // 判断下样机属性,若样机属性是价签出样,则数量为0
                        if (null != attribute && attribute.equals(ModelConstant.MODEL_LABLE)) {
                            commNum = NUM_ZERO;
                        }
                    }
                } else {
                    commNum = NUM_ZERO;
                }
                // 同时需要更新此数量
                modelCheckDaoService.updateCheckCommNum(taskId, storeMan.getStaffId(), locCommCode, commNum, true);
            } else {
                // 判断下样机属性,若样机属性是价签出样,则数量为0
                if (null != attribute && attribute.equals(ModelConstant.MODEL_LABLE)) {
                    commNum = NUM_ZERO;
                }
                // 插入数据
                ModelCheckListBean insertModelCheck = this.makeModelCheck(storeMan, modelCommodity);
                insertModelCheck.setTaskId(taskId);
                insertModelCheck.setStorageCode(storageCode);
                insertModelCheck.setStatus(ModelConstant.CHECK_TASK_STATUS_NO);
                insertModelCheck.setCheckStaff(storeMan.getStaffId());
                insertModelCheck.setCheckCommNum(commNum);
                modelCheckDaoService.upsertModelCheck(insertModelCheck);
            }
            retModelCheck.setCommCode(locCommCode);
            retModelCheck.setCommName(commName);
            retModelCheck.setStorageCode(storageCode);
            retModelCheck.setCommNum(commNum);
            retModelCheck.setAttribute(attribute);
            retModelCheck.setExistFlag(existFlag);
            result.setData(retModelCheck);
        } else {
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
        }
        return result;
    }
    
    /**
     * 判断盘点的商品是否是分配的盘点任务
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param storeCode
     * @param staffId
     * @param taskId
     * @param cateCode
     * @param brandCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private boolean isOwnInventoryBrand(String storeCode, String staffId, Long taskId, String cateCode, String brandCode) {
        ModelTaskAssignDetailsBean bean = modelCheckDaoService.getInventoryTask(storeCode, staffId, taskId, cateCode, brandCode);
        if (null != bean && null != bean.getTaskId() && bean.getTaskId().longValue() > 0) {
            return true;
        }
        return false;
    }

    /**
     * 补充盘点数据信息
     */
    private ModelCheckListBean makeModelCheck(StoreManDto storeMan, ModelCommodityBaseInfo modelCommodity) {
        ModelCheckListBean result = new ModelCheckListBean();
        // 基础信息的门店等信息
        result.setDisCode(storeMan.getRegionCode());
        result.setDisName(storeMan.getRegionName());
        result.setOrgCode(storeMan.getBranchCode());
        result.setOrgName(storeMan.getBranchName());
        result.setStoreCode(storeMan.getStoreCode());
        result.setStoreName(storeMan.getStoreName());
        // 商品信息
        BeanUtil.copyProperties(result, modelCommodity);
        return result;
    }

    /**
     * 扫码盘点商品的数量，若传入的价签id(priceId)不存在则插入 将该数据放入到缓存中，缓存12小时
     */
    private ModelPriceIdCheckBean getTheCommNum(String storeCode, String staffId, String commCode, String priceId) {
        ModelPriceIdCheckBean res = new ModelPriceIdCheckBean();
        Integer result = NUM_ZERO;
        boolean existFlag = false;
        String locPriceId = priceId;
        // 无价签传入则保存default价签
        if (StringUtils.isBlank(locPriceId)) {
            locPriceId = "default";
        }
        try {
            // 价签id间的分割符
            String splitStr = ";";
            String cacheKey = String.format(CacheKeyModelConstants.MODEL_CHECK_PRICE_IDS, storeCode, staffId, commCode);
            String priceIdsStr = cacheUtils.get(cacheKey);
            // 不为空
            if (StringUtils.isNotBlank(priceIdsStr)) {
                String[] priceIds = priceIdsStr.split(splitStr);
                if (null != priceIds) {
                    result = priceIds.length;
                }
                // 将本次的价签id增加到redis缓存中(若不存在才做写入操作且返回结果的价签数量需要加上当前新的这个数量即加1)
                if (!priceIdsStr.contains(locPriceId)) {
                    result++;
                    priceIdsStr += splitStr + locPriceId;
                    cacheUtils.setex(cacheKey, CacheKeyModelConstants.MODEL_CHECK_PRICE_IDS_EXPIRE, priceIdsStr);
                } else {
                    // 价签已存在，已盘点过
                    existFlag = true;
                }
            } else {
                // 为空，直接插入
                result++;
                priceIdsStr = locPriceId;
                cacheUtils.setex(cacheKey, CacheKeyModelConstants.MODEL_CHECK_PRICE_IDS_EXPIRE, priceIdsStr);
            }
        } catch (Exception e) {
            LOGGER.error("样机管理getTheCommNum价签缓存统计盘点样机的数量方法异常", e);
        }
        res.setCheckFlag(existFlag);
        res.setCheckNum(result);
        return res;
    }

    /**
     * 删除价签id缓存数据
     */
    private void delModelPriceIdCheck(String storeCode, String staffId, String commCode) {
        try {
            String cacheKey = String.format(CacheKeyModelConstants.MODEL_CHECK_PRICE_IDS, storeCode, staffId, commCode);
            cacheUtils.del(cacheKey);
        } catch (Exception e) {
            LOGGER.error("样机管理delModelPriceIdCheck价签缓存统计盘点样机的删除该缓存方法异常", e);
        }
    }

    /**
     * 功能描述: <br>
     * 更新盘点商品数量
     *
     * @param storeMan
     * @param taskId
     * @param commCode
     * @param commNum
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("rawtypes")
    public ReturnMsg updateCheckCommNum(StoreManDto storeMan, Long taskId, String commCode, Integer commNum) {
        ReturnMsg result = new ReturnMsg();
        if (null != taskId && StringUtils.isNotBlank(commCode) && null != commNum && commNum >= NUM_ZERO) {
            modelCheckDaoService.updateCheckCommNum(taskId, storeMan.getStaffId(), commCode, commNum, false);
            result.setRetFlag(ReturnMsg.SUCCESS);
        } else {
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 更新样机属性
     * 
     * @param storeMan
     * @param taskId
     * @param commCode
     * @param attribute
     * @param actualCommCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("rawtypes")
    public ReturnMsg updateCheckCommAttribute(StoreManDto storeMan, Long taskId, String commCode, Integer attribute,
            String actualCommCode) {
        ReturnMsg result = new ReturnMsg();
        result.setRetFlag(ReturnMsg.SUCCESS);
        if (null != taskId && StringUtils.isNotBlank(commCode) && null != attribute
                && !(attribute.equals(ModelConstant.MODEL_LABLE) && StringUtils.isBlank(actualCommCode))) {
            String locCommCode = CmmdtyUtils.transform9PartNumber(commCode);
            // 判断输入属性是否为系统常量值，不是入参报错-直接返回
            if (StringUtils.isBlank(ModelConstant.getModelAttributeValue(attribute))) {
                result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                        ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM) + "attribute:" + attribute);
                return result;
            }
            // 价签出样需要更新真实出样商品编码
            if (attribute.equals(ModelConstant.MODEL_LABLE)) {
                String locActualCommCode = CmmdtyUtils.transform9PartNumber(actualCommCode);
                if (null != modelCommodityInfoService.queryCommodityBaseInfo(locActualCommCode)) {
                    // 更新属性
                    modelBlendDaoService.updateModelMainAttribute(storeMan.getStoreCode(), locCommCode, attribute);
                    modelCheckDaoService.updateCheckActualCommCode(taskId, storeMan.getStaffId(), locCommCode,
                            locActualCommCode);
                    // 价签出样，将数量更新为0
                    modelCheckDaoService.updateCheckCommNum(taskId, storeMan.getStaffId(), commCode,
                            ModelConstant.NUM_ZERO, false);
                } else {
                    result.setError(ModelConstant.MODEL_ERROR_NO_COMM,
                            ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_COMM));
                }
            } else {
                // 更新属性
                modelBlendDaoService.updateModelMainAttribute(storeMan.getStoreCode(), locCommCode, attribute);
            }
        } else {
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 删除某条盘点数据
     *
     * @param storeMan
     * @param taskId
     * @param commCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("rawtypes")
    public ReturnMsg delCheckModel(StoreManDto storeMan, Long taskId, String commCode) {
        ReturnMsg result = new ReturnMsg();
        result.setRetFlag(ReturnMsg.SUCCESS);
        if (null != taskId && StringUtils.isNotBlank(commCode)) {
            modelCheckDaoService.deleteModelCheck(taskId, storeMan.getStaffId(), commCode);
            // 清除价签id缓存
            this.delModelPriceIdCheck(storeMan.getStoreCode(), storeMan.getStaffId(), commCode);
        } else {
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 盘点提交
     *
     * @param taskId
     * @param storeMan
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("rawtypes")
    public ReturnMsg sumbitCheck(Long taskId, StoreManDto storeMan) {
        ReturnMsg result = new ReturnMsg();
        result.setRetFlag(ReturnMsg.FAIL);
        if (null != taskId) {
            if (modelBlendDaoService.updateCheckStatusSumbit(taskId, storeMan.getStoreCode(), storeMan.getStaffId())) {
                result.setRetFlag(ReturnMsg.SUCCESS);
            }
        } else {
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
        }
        return result;
    }

}
